import { Button, Space, Row, Col } from 'antd';
import { Field } from 'sula';
import { useState, useEffect, useRef } from 'react';
import type { ButtonProps } from 'antd';

type AddonAfterButton = {
  defaultText: string;
  collapsedText: string;
  props: ButtonProps;
};
type Props = {
  addonAfterButton?: AddonAfterButton;
  fields: any[];
  ctx: any;
};
type DependFieldsItemProps = {
  fieldConfig: any;
  fieldsVisible: boolean;
  formCtx: any;
  onInitValueEmit: (value: any) => any;
};
export const DependFieldsItem: React.FC<DependFieldsItemProps> = ({
  fieldConfig,
  fieldsVisible,
  formCtx,
  onInitValueEmit,
}) => {
  const fieldRef = useRef();
  const { name, dependency = {} } = fieldConfig;
  const mountedRef = useRef(false);
  useEffect(() => {
    if (!mountedRef.current) {
      const { form } = formCtx;
      const fieldValue = form.getFieldValue(name);
      if (fieldsVisible && fieldValue) {
        onInitValueEmit(fieldValue);
        form.setFieldVisible(name, true);
      } else {
        onInitValueEmit(undefined);
        form.setFieldVisible(name, false);
      }
      mountedRef.current = true;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const { form } = formCtx;
    form.setFieldVisible(name, fieldsVisible);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fieldsVisible]);

  return (
    <Field
      {...fieldConfig}
      key={name}
      name={name}
      ref={fieldRef}
      fieldKey={name}
      rules={fieldConfig.rules}
      field={fieldConfig.field}
      remoteSource={fieldConfig.remoteSource}
      initialSource={fieldConfig.initialSource}
      initialValue={fieldConfig.initialValue}
      dependency={dependency}
    />
  );
};

const FieldsCollapse: React.FC<Props> = ({ fields, addonAfterButton, ...restProps }) => {
  const { ctx } = restProps;
  const [fieldsVisible, setFieldsVisible] = useState(true);
  const [fieldsInitValue, setFieldsInitValue] = useState<any[]>([]);
  const primaryFieldConfig = (Array.isArray(fields) && fields[0]) || [];
  const dependFields = fields.slice(1);
  const mountedRef = useRef(false);

  useEffect(() => {
    if (!mountedRef.current) {
      // 当所有子fields上报完成没有值时，将整个控制块初始化为关闭态
      const noneValue = fieldsInitValue.every((val) => {
        return val === undefined;
      });
      if (noneValue) {
        setFieldsVisible(false);
      } else {
        setFieldsVisible(true);
      }
    }
  }, [fieldsInitValue]);
  const getRenderMode = (type: string) => {
    switch (type) {
      case 'radioGroupButton':
      case 'checkbox':
      case 'radio':
      case 'checkboxgroup':
      case 'radiogroup':
        return 'space';
      default:
        return 'row';
    }
  };
  const handleButtonClick = () => {
    // 因为子fields可能存在多个，只有当用户开始点击，可以将组件置为挂载结束状态
    mountedRef.current = true;
    setFieldsVisible(!fieldsVisible);
  };
  const renderMode = getRenderMode(primaryFieldConfig.field.type);
  const fieldNode = (
    <Field
      {...primaryFieldConfig}
      key={primaryFieldConfig.name}
      name={primaryFieldConfig.name}
      fieldKey={primaryFieldConfig.name}
      rules={primaryFieldConfig.rules}
      field={primaryFieldConfig.field}
      remoteSource={primaryFieldConfig.remoteSource}
      initialSource={primaryFieldConfig.initialSource}
      initialValue={primaryFieldConfig.initialValue}
      dependency={primaryFieldConfig.dependency}
    />
  );
  const buttonNode = (
    <Button
      key={`${primaryFieldConfig.name}-button`}
      type="link"
      style={{
        padding: '5px 8px',
      }}
      onClick={() => handleButtonClick()}
      {...addonAfterButton?.props}
    >
      {fieldsVisible
        ? addonAfterButton?.collapsedText || '清除备注'
        : addonAfterButton?.defaultText || '备注'}
    </Button>
  );
  return (
    <>
      {renderMode === 'row' ? (
        <Row justify="space-around" align="top">
          <Col span={22}>{fieldNode}</Col>
          <Col span={2}>{buttonNode}</Col>
        </Row>
      ) : (
        <Space
          key={`${primaryFieldConfig.name}-space`}
          style={{ display: 'flex' }}
          align="baseline"
        >
          {fieldNode}
          {buttonNode}
        </Space>
      )}
      {fieldsVisible &&
        dependFields.map((fieldConfig) => {
          return (
            <DependFieldsItem
              fieldConfig={fieldConfig}
              formCtx={ctx}
              key={`${fieldConfig.name}-dependFieldsItem`}
              fieldsVisible={fieldsVisible}
              onInitValueEmit={(value) => {
                const fieldsInitValueTemp = [...fieldsInitValue];
                fieldsInitValueTemp.push(value);
                setFieldsInitValue(fieldsInitValueTemp);
              }}
            />
          );
        })}
    </>
  );
};

export default FieldsCollapse;
